// 顶部：拆分 logger 的值/类型导入
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, ResponseType } from 'axios';
import type { ICallbackParams, IParams } from './request';
import Logger from '../logger';
import type { ILogger } from '../logger';
import { TYPE } from './config';

// 新增：统一转换函数，返回 ReadableStream<Uint8Array>
function toWebReadableStream(node: any): ReadableStream<Uint8Array> {
    return new ReadableStream<Uint8Array>({
        start(controller) {
            const onData = (chunk: any) => {
                let bytes: Uint8Array;
                if (chunk instanceof Uint8Array) {
                    bytes = chunk;                 // Buffer 也是 Uint8Array 的子类
                } else if (typeof chunk === 'string') {
                    bytes = new TextEncoder().encode(chunk);
                } else {
                    bytes = new TextEncoder().encode(String(chunk));
                }
                try { controller.enqueue(bytes); } catch { /* noop */ }
            };
            const onEnd = () => { try { controller.close(); } catch { /* noop */ } };
            const onError = (err: any) => { try { controller.error(err); } catch { /* noop */ } };

            node.on?.('data', onData);
            node.on?.('end', onEnd);
            node.on?.('close', onEnd);
            node.on?.('error', onError);
        },
        cancel() {
            try { node.destroy?.(); } catch { /* noop */ }
        },
    });
}

const sendAxiosRequest = async <T>(params: IParams, callbackParams?: ICallbackParams): Promise<T> => {
    callbackParams = callbackParams || {};
    const logger: ILogger = new Logger(TYPE.Axios, params.loggerLevel);

    const axiosConfig: AxiosRequestConfig = {
        url: params.url,
        method: params.method,
        data: params.requestBody,
        headers: params.headers.reduce((acc, header) => {
            acc[header.name] = header.value;
            return acc;
        }, {} as Record<string, string>),
        timeout: params.timeout,
        responseType: params.responseType === '' ? undefined : params.responseType as ResponseType,
    };

    logger.debug('axiosConfig', axiosConfig);

    const axiosInstance: AxiosInstance = axios.create();

    // 请求拦截器
    axiosInstance.interceptors.request.use(config => {
        logger.debug('Request Interceptor', config);
        return config;
    }, error => {
        logger.error('Request Interceptor Error', error.toString());
        return Promise.reject(error);
    });

    // 响应拦截器
    axiosInstance.interceptors.response.use((response: AxiosResponse<T>) => {
        logger.debug('Response Interceptor', response);
        return response;
    }, error => {
        const cfg: AxiosRequestConfig | undefined = error.config;
        if (axios.isCancel(error)) {
            logger.info('Request canceled', error.message);
            callbackParams?.handleAbort?.();
        } else {
            callbackParams?.handleError?.({
                code: error.response?.status || -1,
                msg: error.message,
                method: cfg?.method,
                url: cfg?.url,
                params: cfg?.data,
                headers: cfg?.headers,
                error: error.response?.data ?? (typeof error.toJSON === 'function' ? error.toJSON() : String(error)),
            });
        }
        return Promise.reject(error);
    });

    if (callbackParams?.requestInstance) {
        const source = axios.CancelToken.source();
        axiosConfig.cancelToken = source.token;
        callbackParams.requestInstance(source);
    }

    try {
        const response = await axiosInstance.request<T>(axiosConfig);

        // 如果请求的是数据流，统一返回 Web ReadableStream<Uint8Array>
        if (response.config.responseType === 'stream') {
            logger.info('成功获取响应数据流');
            const nodeStream: any = (response as any).data;

            // 核心：转换为 Web ReadableStream，便于 getReader() 消费（与 Fetch 一致）
            const webStream = toWebReadableStream(nodeStream);
            return webStream as unknown as T;
        }

        return response.data;
    } catch (error) {
        // 错误已在响应拦截器中处理
        throw error;
    }
};

export default sendAxiosRequest;